#![feature(destructuring_assignment)]
extern crate usrtrust;
use rand;

use usrtrust::{HeapIndex,Heap,HeapSized};
use usrtrust::{ULogs,Environment};
use std::path::{Path};
use std::io::{Write,Result};
#[derive(Debug)]
pub struct UTArray<const L: usize> 
    where [u8;L]: Sized {
    pub b:[usize;L]
}

impl<const L: usize> HeapIndex for UTArray<{L}> {
    type Output = usize;
    fn less(&self,a:usize,b:usize) -> bool {
        self.b[a]<self.b[b]
    }
    fn swap(&mut self,a:usize,b:usize) {
        (self.b[a],self.b[b]) = (self.b[b],self.b[a])
    }
    fn hindex<'a>(&'a self, idx: usize) -> &'a usize { &self.b[idx] }
    fn hindex_mut<'a>(&'a mut self, idx: usize) -> &'a mut usize{
        &mut self.b[idx]
    }
}

impl<const L: usize> Default for UTArray<{L}> {
    fn default() -> Self {UTArray::<{L}>{b:[0usize;L]}}
}

#[derive(Default)]
struct HeapTestConfig {}

impl HeapSized for HeapTestConfig {
    const BUF_LEN:usize = 1024_usize;
    const HEAD_START:usize = 0_usize;
    type BufArray = UTArray<{Self::BUF_LEN}>;
    type Item = usize; 
}

fn main() -> Result<()> {
    let e = Environment::from_dir(Path::new("/tmp/usrtos"))?;
    let logt = ULogs::from_env(&e);
    let mut h = Heap::<HeapTestConfig>::default();
    for i in 0usize..10usize {
        let y = rand::random::<usize>() % 1000usize;
        let ins = h.insert(y);
        println!("insert {} {:?}",i,ins);
        writeln!(*logt.info(),"insert {} {:?}",i,ins);
        h.dump(&mut *logt.info());
    }
    for i in 0..11 {
        let pp = h.pop();
        println!("pop {} {:?}",i,pp);
        writeln!(*logt.info(),"pop {} {:?}",i,pp);
        h.dump(&mut *logt.info());
    }
    Ok(())
}